package com.wisdom.smartbook.activity;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Point;
import android.hardware.Camera;
import android.media.ExifInterface;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import com.tencent.smtt.sdk.WebView;
import com.wisdom.smartbook.R;
import com.wisdom.smartbook.app.MyApp;
import com.wisdom.smartbook.base.BaseActivity;
import com.wisdom.smartbook.facelib.core.AndroidConfig;
import com.wisdom.smartbook.facelib.core.FaceCheckManager;
import com.wisdom.smartbook.facelib.core.model.FaceLandmarkInfo;
import com.wisdom.smartbook.facelib.encoder.EncoderBus;
import com.wisdom.smartbook.facelib.engine.CameraEngine;
import com.wisdom.smartbook.facelib.engine.CheckFaceEngine;
import com.wisdom.smartbook.facelib.view.FaceRectView;
import com.wisdom.smartbook.listener.CameraPreviewListener;
import com.wisdom.smartbook.permission.PermissionUtils;
import com.wisdom.smartbook.utils.ActivityManagerUtils;
import com.wisdom.smartbook.utils.DisplayUtil;
import com.wisdom.smartbook.utils.FileManager;
import com.wisdom.smartbook.utils.FileTool;
import com.wisdom.smartbook.utils.KLog;
import com.wisdom.smartbook.utils.SensorEventUtil;
import com.wisdom.smartbook.utils.ToastUtils;
import com.wisdom.smartbook.utils.camera.CameraHelper;
import com.wisdom.smartbook.utils.camera.CameraListener;
import com.wisdom.smartbook.widget.CircleCameraPreview;
import com.wisdom.smartbook.widget.TextureVideoViewOutlineProvider;

import org.jetbrains.annotations.NotNull;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * 人脸识别逻辑
 */
public class FaceRecognizeActivity extends BaseActivity implements ViewTreeObserver.OnGlobalLayoutListener {

    private CameraHelper cameraHelper;
    protected Camera.Size previewSize;
    /**
     * 优先打开的摄像头，本界面主要用于单目RGB摄像头设备，因此默认打开前置
     */
    private Integer rgbCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;

    /**
     * 相机预览显示的控件，可为SurfaceView或TextureView
     */
    protected View mTtcVideoView;
    /**
     * 相机预览显示的控件，可为SurfaceView或TextureView
     */
    private CircleCameraPreview previewView;

    protected FrameLayout mRootView;

    protected WebView mWebView;

    private CameraPreviewListener mCameraPreviewListener;

    private FrameLayout mFrameLayout;

    private FaceRectView mFaceRectView;
    private TextView mCountDownTv;
    // 相机的数据 nv21格式
    protected byte[] mNV21Bytes;


    private Runnable imageConverter;

    protected String imageFilePath;

    public static final int CAMERA_REQUEST_CODE = 10001; //拍照


    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    protected void initView() {
        mCountDownTv = findViewById(R.id.tv_countDown);
        mFaceRectView = findViewById(R.id.facerectview);
        mFrameLayout = findViewById(R.id.fram_content);
        mRootView = findViewById(R.id.root_view);
        mTtcVideoView = findViewById(R.id.rtc_video_view);
        mWebView = findViewById(R.id.main_webview);
        previewView = findViewById(R.id.camera_texture_preview);

        mRootView = findViewById(R.id.root_view);
        mWebView = findViewById(R.id.main_webview);

        int width = DisplayUtil.getScreenHeightPixels(mActivity);

        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mFrameLayout.getLayoutParams();
        layoutParams.width = (int) (width * 0.9);
        layoutParams.height = (int) (width * 0.9);
        mFrameLayout.setLayoutParams(layoutParams);
    }

    SensorEventUtil sensorEventUtil;

    @Override
    protected void initData() {

    }

    public void faceinit() {

        /**
         * 初始化
         * */
        FaceCheckManager.init(
                FaceRecognizeActivity.this,
                AndroidConfig
                        .create()
                        .setCameraMode()
                        .setDefaultFunc().openFunc(AndroidConfig.Func.Attribution)
                        .setDefaultInputImageFormat()
                        .setInputImageSize(previewWidth, previewHeight)
                        .setOutputImageSize((int) ScreenWidth, (int) ScreenHeight)
        );


    }

    public void onClickClose(View view) {

        mTtcVideoView.setVisibility(View.GONE);
        release();
    }

    public void setCameraPreviewListener(CameraPreviewListener cameraPreviewListener) {
        mCameraPreviewListener = cameraPreviewListener;
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (cameraHelper != null) {
            cameraHelper.start();
        }
    }

    @Override
    protected void onDestroy() {


        KLog.d(this.getClass().getSimpleName(), " onDestroy() ");
        release();

        super.onDestroy();
    }

    protected void release() {
        mHandler.removeCallbacks(mRunnable);
        if (mCusCountDownTimer != null) {
            mCusCountDownTimer.cancel();
            mCusCountDownTimer = null;
        }
        if (cameraHelper != null) {
            cameraHelper.release();
            cameraHelper = null;
        }

    }

    // 照相机预览宽
    public int previewWidth = 0;
    // 照相机预览高
    public int previewHeight = 0;
    // 展示区域宽
    public static float ScreenWidth;
    // 展示区域高
    public static float ScreenHeight;


    protected void initCamera() {
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        CameraListener cameraListener = new CameraListener() {
            @Override
            public void onCameraOpened(Camera camera, int cameraId, int displayOrientation, boolean isMirror) {
                Camera.Size lastPreviewSize = previewSize;
                previewSize = camera.getParameters().getPreviewSize();

            }


            @Override
            public void onPreview(final byte[] nv21, Camera camera) {
                if (MyApp.getInstance().isLoginSuccess()) {
                    mHandler.removeCallbacks(mRunnable);
                    return;
                }
                if (sensorEventUtil == null) {
                    if (camera.getParameters() == null) {
                        return;
                    }
                    Camera.Size previewSize = camera.getParameters().getPreviewSize();
                    previewHeight = previewSize.height;
                    previewWidth = previewSize.width;
                    faceinit();
                    EncoderBus.GetInstance().onSetFrameConfiguration(previewHeight, previewWidth);
                }
                imageConverter = () -> mNV21Bytes = nv21;
                mHandler.post(mRunnable);
            }


            @Override
            public void onCameraClosed() {
                KLog.i("onCameraClosed: ");
            }

            @Override
            public void onCameraError(Exception e) {
                KLog.i("onCameraError: " + e.getMessage());
            }

            @Override
            public void onCameraConfigurationChanged(int cameraID, int displayOrientation) {
                KLog.i("onCameraConfigurationChanged: " + cameraID + "  " + displayOrientation);
            }
        };

        cameraHelper = new CameraHelper.Builder()
                .previewViewSize(new Point(previewView.getMeasuredWidth(), previewView.getMeasuredHeight()))
                .rotation(getWindowManager().getDefaultDisplay().getRotation()).
                        specificCameraId(rgbCameraID != null ? rgbCameraID : Camera.CameraInfo.CAMERA_FACING_FRONT)
                .isMirror(false).previewOn(previewView)
                .cameraListener(cameraListener).build(mActivity);
        cameraHelper.init();
        cameraHelper.start();
    }


    //得到最新的bytes
    protected void getCameraBytes() {
        if (imageConverter != null) {
            imageConverter.run();
        }
    }

    /**
     * 在{@link #previewView}第一次布局完成后，去除该监听，并且进行引擎和相机的初始化
     */
    @Override
    public void onGlobalLayout() {
        previewView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        //激活引擎
        initCamera();
    }

    CusCountDownTimer mCusCountDownTimer;

    public void setFaceRecog() {
        if (mFaceRectView != null) {
            mFaceRectView.clearFaceInfo();
        }
        mCountDownTv.setVisibility(View.VISIBLE);

        mTtcVideoView.setVisibility(View.VISIBLE);
        //在布局结束后才做初始化操作
        previewView.setClipToOutline(true);
        previewView.setOutlineProvider(new TextureVideoViewOutlineProvider(33));
        previewView.getViewTreeObserver().addOnGlobalLayoutListener(this);

        mCusCountDownTimer = new CusCountDownTimer(61000, 1000);
        mCusCountDownTimer.start();
    }

    private class CusCountDownTimer extends CountDownTimer {


        public CusCountDownTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            int second = (int) (millisUntilFinished / 1000);
            mCountDownTv.setText(second + "秒");
        }

        @Override
        public void onFinish() {
            mTtcVideoView.setVisibility(View.GONE);
            release();
        }
    }

    Handler mHandler = new Handler();
    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            if (!MyApp.getInstance().isLoginSuccess()) {
                processImage();
            }
        }
    };

    public void processImage() {

        if (sensorEventUtil != null) {
            getCameraBytes();
            int degree = CameraEngine.getInstance().getCameraOrientation(sensorEventUtil.orientation);
            /**
             * 设置旋转角
             */
            FaceCheckManager.Camera.setRotation(degree - 90, false, (int) MainActivity.ScreenWidth, (int) MainActivity.ScreenHeight);

            /**
             * 获取人脸信息
             */
            long start = System.currentTimeMillis();
            try {
                FaceCheckManager.FaceDetect faceDetect = FaceCheckManager.detect(mNV21Bytes);
                long end = System.currentTimeMillis();
                KLog.d("时长 " + (end - start));
                if (faceDetect.getFaceCount() > 0) {
                    if (mFaceRectView != null) {
                        mFaceRectView.clearFaceInfo();
                    }
                    mFaceRectView.post(new Runnable() {
                        @Override
                        public void run() {
                            mFaceRectView.addFaceInfo(faceDetect);
                        }
                    });
                    KLog.d("识别到人脸");
                    if (mCameraPreviewListener != null) {
                        mCameraPreviewListener.onPreview(mNV21Bytes, previewSize.width, previewSize.height);
                    }
                } else {
                    if (mFaceRectView != null) {
                        mFaceRectView.clearFaceInfo();
                    }
//                    CheckFaceEngine.getInstance().noFace();
                    KLog.d("请将人脸放入取景框内");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public void selectOnclick() {

        PermissionUtils.getInstance().checkPermissions(this, new PermissionUtils.onPermissionsResultListener() {
            @Override
            public void onPermissionGranted() {
                openAlbum();
            }

            @Override
            public void onPermissionDenied(List<String> permissionList, String permissionsHint) {
                ToastUtils.showShortSafe("必要权限被拒绝，功能不可用！");

            }
        });
    }

    private void openAlbum() {
        Uri mOriginUri;
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        imageFilePath = FileManager.getImageCachePath(mContext) + File.separator + System.currentTimeMillis() + ".jpg";
        if (new File(imageFilePath).exists()) new File(imageFilePath).delete();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mOriginUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".fileProvider",
                    new File(imageFilePath));
        } else {
            mOriginUri = Uri.fromFile(new File(imageFilePath));
        }
        KLog.d("imageFilePath=" + imageFilePath);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mOriginUri);
        startActivityForResult(intent, CAMERA_REQUEST_CODE);
    }


    /**
     * 读取图片属性：旋转的角度
     *
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /*
     * 旋转图片
     * @param angle
     * @param bitmap
     * @return Bitmap
     */
    public Bitmap rotaingImageView(int angle, Bitmap bitmap) {
        //旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 创建新的图片
        Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//        ivPhoto.setImageBitmap(bitmap1); // 展示刚拍过的照片
        return bitmap1;
    }

    public void saveBitmapFileToFile(Bitmap bitmap, String pathname) {
        File filemm = null;
        if (TextUtils.isEmpty(pathname)) {
            filemm = new File(imageFilePath); //
        } else {
            filemm = new File(pathname); //
        }
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filemm));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //说明第一个参数上下文，第二个参数是文件路径例如：/storage/emulated/0/1621832516463_1181875151.mp4 第三个参数是文件类型，传空代表自行根据文件后缀判断刷新到相册
        MediaScannerConnection.scanFile(mContext, new String[]{imageFilePath}, null, new MediaScannerConnection.OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                //刷新成功的回调方法
                Log.e("资源刷新成功路径为", path);
            }
        });
    }

}
